home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / sysdep1.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  29KB  |  927 lines

  1. /************************************************************************/
  2. /*                              sysdep1.c                               */
  3. /*                                                                      */
  4. /*      This is the repository of most of the system dependent code     */
  5. /*      in Citadel.  We hope, pray, and proselytize, at least.          */
  6. /************************************************************************/
  7. /************************************************************************/
  8. /*                              history                                 */
  9. /*                                                                      */
  10. /* 89Oct16 AP   Amiga                                                   */
  11. /* 87Apr01 HAW  File tagging completed; bug for .RD/.RE fixed.          */
  12. /* 86Dec14 HAW  Reorganized into areas.                                 */
  13. /* 86Nov25 HAW  Created.                                                */
  14. /************************************************************************/
  15. #define SYSTEM_DEPENDENT
  16. #define TIMER_FUNCTIONS_NEEDED
  17. #include "ctdl.h"
  18. #include "dos.h"
  19. #include "time.h"
  20. #include "string.h"
  21. #include "stdarg.h"
  22.  
  23. #define EXTERN extern
  24. #include "global_data.h"
  25.  
  26. /************************************************************************/
  27. /*                              Contents                                */
  28. /*                                                                      */
  29. /*              AREAS:                                                  */
  30. /*      bigDirectory()          gets an "extended" directory            */
  31. /* #    bigDirs()               work function for bigDirectory()        */
  32. /*      freeFileList()          Free file list                          */
  33. /*      getArea()               get an area from the sysop              */
  34. /*      goodArea()              get good area                           */
  35. /*      homeSpace()             takes us to our home space              */
  36. /*      netGetArea()            get area for dumping networked file(s)  */
  37. /*      netSetNewArea()         set area for dumping networked file(s)  */
  38. /*      prtNetArea()            makes human readable form of NET_AREA   */
  39. /*      setSpace()              goto specified "area"                   */
  40. /* #    realSetSpace()          does work of setSpace, others           */
  41. /* #    MSDOSparse()            parses a string for MSDOS filename      */
  42. /* #    fileType()              gets file type for MSDOS                */
  43. /*      sysGetSendFiles()       specify where to send files from        */
  44. /*      updFiletag()            updates a filetag                       */
  45. /*      sysRoomLeft()           how much room left in net recept area   */
  46. /* #    getSize()               gets size of a file                     */
  47. /*      sysSendFiles()          system dep stuff for sending files      */
  48. /* #    doSendWork()            does work of sysSendFiles()             */
  49. /*              BAUD HANDLER:                                           */
  50. /* #    check_CR()              scan input for carriage returns         */
  51. /*      Find_baud()             does flip flop search for baud          */
  52. /*      getNetBaud()            check for baud of network caller        */
  53. /*              CONSOLE HANDLING:                                       */
  54. /*      KBReady()               returns TRUE if a console char is ready */
  55. /*      mputChar()              Do our own for some Console output      */
  56. /*                                                                      */
  57. /*              # == local for this implementation only                 */
  58. /************************************************************************/
  59. #define NO_IDEA         0
  60. #define SINGLE_FILE     1
  61. #define IS_DIR          2
  62. #define AMB_FILE        3
  63. /************************************************************************/
  64. /*      Globals -- there shouldn't be anything here but statics and     */
  65. /*      externs.                                                        */
  66. /************************************************************************/
  67. /* These MUST be defined! */
  68. /* short ConDelay; */
  69.  
  70. int Jsystem(char *);
  71. void Do_Stack_Check(void);
  72.  
  73. char *rates[] =
  74.   {
  75.   "300",   "1200",  "2400",   "4800",    "9600",
  76.   "14400", "19200", "38400", "57600", "Unknown"
  77.  
  78.   };
  79. static short LastBaudIndex;
  80.  
  81. /* Here's the rest of the goo */
  82. extern logBuffer logBuf;         /* Log buffer of a person       */
  83. extern SListBase ResList;
  84. extern aRoom     roomBuf;
  85. extern MessageBuffer   msgBuf;
  86. extern CONFIG    cfg;            /* Lots an lots of variables    */
  87. extern char onConsole;                  /* Who's in control?!?          */
  88. extern char whichIO;                    /* CONSOLE or MODEM             */
  89. extern char anyEcho;
  90. extern char echo;
  91. extern FILE *upfd;
  92. extern char modStat;
  93. extern char echoChar;
  94. extern char haveCarrier;
  95. extern long netBytes;
  96. extern char outFlag;
  97. extern char *indexTable;
  98. void *ChPhrase(DirEntry *e, DirEntry *d);
  99. /************************************************************************/
  100. /* Section 3.4. AREAS:                                                  */
  101. /*   The model of Citadel includes a provision for "directory rooms."   */
  102. /* A directory room is defined as the ability to look in on some section*/
  103. /* of the host system's file section.  In order to avoid tying the      */
  104. /* directory structure of Citadel to any particular operating system, an*/
  105. /* "abstraction" has been implemented.  Each room that has been desig-  */
  106. /* nated as a directory will have an "area" associated with it.  This   */
  107. /* "area" is dependent on each implementation; access to "areas" is     */
  108. /* through routines located in this module.  Therefore, the abstract    */
  109. /* directory model of Citadel is in the main code modules, and should   */
  110. /* not require any changes from port to port.  The only changes neces-  */
  111. /* sary should be in this file (SYSDEP.C), where the porter must decide */
  112. /* upon and implement a mapping of how a directory room peeks in on his */
  113. /* or her file system.                                                  */
  114. /*   Basically, the routines are fairly simple in purpose.              */
  115. /*                                                                      */
  116. /*      "And if pigs had wings they could fly!"                         */
  117. /************************************************************************/
  118. char        ourHomeSpace[150];
  119. char MatchList[] = ".-_*?";
  120. /************************************************************************/
  121. /*      ValidDirFileName() validate a file name                         */
  122. /************************************************************************/
  123. char ValidDirFileName(char *ptr)
  124.   {
  125.   Do_Stack_Check();
  126.   while (*ptr)
  127.     {
  128.     if (isalpha(*ptr) || isdigit(*ptr) || strchr(MatchList, *ptr))
  129.     ++ptr;
  130.     else
  131.     return FALSE;
  132.  
  133.     }
  134.   return TRUE;
  135.  
  136.   }
  137. /************************************************************************/
  138. /*      RoomLeft() how much room left on this disk or whatever?         */
  139. /*      NB: Returns in K, not bytes!                                    */
  140. /************************************************************************/
  141. long RoomLeft(aRoom *room)
  142.   {
  143.   char *temp, dir[150];
  144.   long temp3, temp2;
  145.   long toReturn;
  146.   /* this should never happen, but just in case ... */
  147.   Do_Stack_Check();
  148.   if ((temp = FindDirName(room->rbArea)) == NULL)  return 0;
  149.   strCpy(dir, temp);
  150.   diskSpaceLeft(dir, &temp3, &temp2);
  151.   toReturn = temp2 / 1024l;
  152.   return toReturn;
  153.  
  154.   }
  155.  
  156. /************************************************************************/
  157. /*      getArea() get area to assign to a directory room from sysop     */
  158. /*      returns FALSE if problems or abort                              */
  159. /************************************************************************/
  160. char getArea(aRoom *roomData)
  161.   {
  162.   char dir[200];
  163.   SYS_FILE filename;
  164.   extern char *DirFileName;
  165.   extern SListBase DirBase;
  166.   Do_Stack_Check();
  167.   if (!goodArea("DIRNAM", dir))
  168.     {
  169.     return FALSE;
  170.  
  171.     }
  172.   makeSysName(filename, DirFileName, &cfg.roomArea);
  173.   upfd = safeopen(filename, WRITE_TEXT);
  174.   AddData(&DirBase, NtoStrInit(roomData->rbArea, dir, 0, FALSE),
  175.   WrtNtoStr, /* Kill duplicates */ TRUE);
  176.   fclose(upfd);
  177.   return TRUE;
  178.  
  179.   }
  180. /************************************************************************/
  181. /*      fileType() gets file type for MSDOS                             */
  182. /************************************************************************/
  183. fileType(char *theDir)
  184.   {
  185.   FILE *fd;
  186.   Do_Stack_Check();
  187.   if (strchr(theDir, '*') != NULL ||
  188.   strchr(theDir, '?') != NULL)
  189.     {
  190.     return AMB_FILE;
  191.  
  192.     }
  193.   if (realSetSpace(theDir))
  194.     {
  195.     homeSpace();
  196.     return IS_DIR;
  197.  
  198.     }
  199.   if ((fd = safeopen(theDir, READ_TEXT)) != NULL)
  200.     {
  201.     fclose(fd);
  202.     return SINGLE_FILE;
  203.  
  204.     }
  205.   return NO_IDEA;
  206.  
  207.   }
  208. /************************************************************************/
  209. /*      goodArea() Gets a valid path from the sysop. Drive should be    */
  210. /*                  set already.                                        */
  211. /************************************************************************/
  212. goodArea(char *prompt, char *dir)
  213.   {
  214.   int  c;
  215.   char dir_x[150];
  216.   Do_Stack_Check();
  217.   while (TRUE)
  218.     {
  219.     if (!getXString(prompt, dir_x, 149, "", ""))
  220.     return FALSE;
  221.     c = fileType(dir_x);
  222.     switch (c)
  223.       {
  224.       case IS_DIR:
  225.       strCpy(dir, dir_x);
  226.       return TRUE;
  227.       case NO_IDEA:
  228.       if (strLen(dir_x) != 0)
  229.         {
  230.         Output_Citadel_Message("DNTEXS",(long)dir_x,NULL,NULL);
  231.         if (getYesNo("CREATE"))
  232.           {
  233.           if (mkdir(dir_x) != 0)
  234.             {
  235.             Output_Citadel_Message("ERRDIR",(long)dir_x,NULL,NULL);
  236.             homeSpace();
  237.  
  238.             }
  239.           else
  240.             {
  241.             homeSpace();
  242.             strCpy(dir, dir_x);
  243.             return TRUE;
  244.  
  245.             }
  246.  
  247.           }
  248.  
  249.         }
  250.       else
  251.         {
  252.         strCpy(dir, dir_x);
  253.         return TRUE;
  254.  
  255.         }
  256.       break;
  257.       default:
  258.         Output_Citadel_Message("ERRNDR",(long)dir_x,NULL,NULL);
  259.       }
  260.  
  261.     }
  262.  
  263.   }
  264. /************************************************************************/
  265. /*      homeSpace() takes us home!                                      */
  266. /************************************************************************/
  267. void homeSpace()
  268.   {
  269.   Do_Stack_Check();
  270.   realSetSpace(ourHomeSpace);
  271.   }
  272. /************************************************************************/
  273. /*      netGetArea() Get area to store a file from networking           */
  274. /************************************************************************/
  275. netGetAreaV2(MenuId id,char *fn, struct fl_req *file_data, char ambiguous)
  276.   {
  277.   char goodname;
  278.   Do_Stack_Check();
  279.   if (!goodArea("DIRNSY", file_data->flArea.naDirname)) return FALSE;
  280.   if (!ambiguous)
  281.     {
  282.     realSetSpace(file_data->flArea.naDirname);
  283.     do
  284.       {
  285.       if (!getXString("FILNSY",file_data->filename, NAMESIZE, fn, fn))
  286.         {
  287.         homeSpace();
  288.         return FALSE;
  289.  
  290.         }
  291.       if (access(file_data->filename, 0) == 0)
  292.         {
  293.         Output_Citadel_Message("AREXTS",(long)file_data->filename,NULL,NULL);
  294.         goodname = SysopGetYesNo(id,"ISTHIS","THEPRM");
  295.  
  296.         }
  297.       else goodname = TRUE;
  298.  
  299.       }
  300.     while (!goodname);
  301.     homeSpace();
  302.  
  303.     }
  304.   else
  305.     {
  306.     Output_Citadel_Message("AMBFRS",NULL,NULL,NULL);
  307.     file_data->filename[0] = 0;
  308.     return FALSE;
  309.     }
  310.   return TRUE;
  311.  
  312.   }
  313. /************************************************************************/
  314. /*      prtNetArea() human readable form of a NET_AREA                  */
  315. /************************************************************************/
  316. char *prtNetArea(NET_AREA *netArea)
  317.   {
  318.   Do_Stack_Check();
  319.   return netArea->naDirname;
  320.  
  321.   }
  322. /************************************************************************/
  323. /*      dirString() a directory string                                                                          */
  324. /************************************************************************/
  325. void dirString(char *target, ROOM_AREA *area)
  326.   {
  327.   char *temp;
  328.   Do_Stack_Check();
  329.   if ((temp = FindDirName(*area)) != NULL)
  330.   strCpy(target, temp);
  331.   else strCpy(target, "ERROR");
  332.  
  333.   }
  334. /************************************************************************/
  335. /*      realSetSpace() does work of setSpace                            */
  336. /************************************************************************/
  337. char currentdir[150];
  338. char realSetSpace(char *dir)
  339.   {
  340.   extern FILE *netLog;
  341.   char result;
  342.   Do_Stack_Check();
  343.   if (cfg.BoolFlags.debug)
  344.     {
  345.     splitF(netLog,"Changing from %s\n",currentdir);
  346.     splitF(netLog,"To:%s\n",dir);
  347.     };
  348.   strcpy(currentdir,dir);
  349.   SpecialMessage(dir);
  350.   result = (char )(chdir(dir)== 0 );
  351.   return result;
  352.   }
  353. /************************************************************************/
  354. /*      FindDirName() finds the directory associated with some room     */
  355. /************************************************************************/
  356. char *FindDirName(int roomNo)
  357.   {
  358.   Do_Stack_Check();
  359.   return (char *)
  360.   SearchList(&DirBase, NtoStrInit(roomNo, "", 0, TRUE));
  361.  
  362.   }
  363. /************************************************************************/
  364. /*      setSpace() moves us to an area                                  */
  365. /************************************************************************/
  366. char setSpace(aRoom *roomData)
  367.   {
  368.   char   *temp;
  369.   extern SListBase DirBase;
  370.   Do_Stack_Check();
  371.   if ((temp = FindDirName(roomData->rbArea)) == NULL)
  372.     {
  373.     Output_Citadel_Message("ERRDRM",NULL,NULL,NULL);
  374.     return FALSE;
  375.  
  376.     }
  377.   if (!realSetSpace(temp))
  378.     {
  379.     Output_Citadel_Message("ERRDME",(long)temp,NULL,NULL);
  380.     return FALSE;
  381.  
  382.     }
  383.   return TRUE;
  384.  
  385.   }
  386. #ifdef READY
  387. /************************************************************************/
  388. /*      writeArea(x) prints the area associated with this room          */
  389. /************************************************************************/
  390. void writeArea(char rightNow, aRoom *roomData, char *buf)
  391.   {
  392.   Do_Stack_Check();
  393.   if (rightNow)
  394.   mPrintf("%s\n ", FindDirName(roomData->rbArea));
  395.   else
  396.     {
  397.     if (strLen(FindDirName(roomData->rbArea)) != 0)
  398.     sPrintf(buf, "'%s'", FindDirName(roomData->rbArea));
  399.     else
  400.     sPrintf(buf, "'%c:'", locDisk);
  401.  
  402.     }
  403.  
  404.   }
  405. #endif
  406. /************************************************************************/
  407. /*      sysGetSendFiles() where to find files to send to another system */
  408. /************************************************************************/
  409. char sysGetSendFilesV2(MenuId id,char *name, struct fl_send *sendWhat)
  410.   {
  411.   Do_Stack_Check();
  412.   strCpy(sendWhat->snArea.naDirname, name);
  413.   if (fileType(sendWhat->snArea.naDirname) == NO_IDEA)
  414.     {
  415.     if (SysopGetYesNo(id,NULL,"FILDIR"))
  416.     return TRUE;
  417.     return FALSE;
  418.  
  419.     }
  420.   return TRUE;
  421.  
  422.   }
  423. /************************************************************************/
  424. /*      MoveFile() move a file to a new name and location               */
  425. /************************************************************************/
  426. void MoveFile(char *oldname, char *newname)
  427.   {
  428.   char buffer[100];
  429.   FILE *infd, *outfd;
  430.   int s;
  431.   Do_Stack_Check();
  432.   if (toUpper(*oldname) == toUpper(*newname))
  433.     {
  434.     rename(oldname, newname);
  435.     if (access(newname, 0) == 0) return;
  436.  
  437.     }
  438.   sPrintf(buffer, "copy >NIL: %s %s", oldname, newname);
  439.   Jsystem(buffer);
  440.   if (access(newname, 0) == 0)
  441.     {
  442.     unlink(oldname);
  443.  
  444.     }
  445.   else
  446.     {
  447.     if ((infd = safeopen(oldname, READ_ANY)) == NULL) return;
  448.     if ((outfd = safeopen(newname, WRITE_ANY)) == NULL)
  449.       {
  450.       fclose(infd);
  451.       return;
  452.  
  453.       }
  454.     while ((s = fread(buffer, sizeof buffer, 1, infd)) > 0)
  455.     fwrite(buffer, s, 1, outfd);
  456.     fclose(infd);
  457.     fclose(outfd);
  458.     unlink(oldname);
  459.  
  460.     }
  461.  
  462.   }
  463. /************************************************************************/
  464. /*      sysRoomLeft() how much room left in net recept area             */
  465. /************************************************************************/
  466. long sysRoomLeft()
  467.   {
  468.   long temp, temp2, temp3;
  469.   Do_Stack_Check();
  470.   temp = (long) ( (long) cfg.sizeArea * 1024);
  471.   netBytes = 0l;
  472.   doSendWork(ALL_FILES, getSize);
  473.   diskSpaceLeft(NULL, &temp3, &temp2);
  474.   return (minimum(temp - netBytes, temp2));
  475.  
  476.   }
  477. /************************************************************************/
  478. /*      sysSendFiles() system dep stuff for sending files               */
  479. /************************************************************************/
  480. void sysSendFiles(struct fl_send *sendWhat)
  481.   {
  482.   char   temp[100], *last;
  483.   label  mask;
  484.   Do_Stack_Check();
  485.   strCpy(temp, sendWhat->snArea.naDirname);
  486.   switch (fileType(sendWhat->snArea.naDirname))
  487.     {
  488.     case IS_DIR:
  489.     strCpy(mask, "*");
  490.     break;
  491.     case SINGLE_FILE:
  492.     case AMB_FILE:
  493.     if ((last = strrchr(temp, '/')) == NULL &&
  494.     (last = strrchr(temp, ':')) == NULL)
  495.       {
  496.       strCpy(mask, temp);
  497.       temp[0] = 0;
  498.  
  499.       }
  500.     else
  501.       {
  502.       strCpy(mask, last + 1);
  503.       if (last != temp && *last != ':')
  504.       *last = 0;
  505.       else
  506.       *(last + 1) = 0;
  507.  
  508.       }
  509.     break;
  510.     case NO_IDEA:
  511.     default:
  512.     sPrintf(temp, "Couldn't do anything with '%s'.",
  513.     sendWhat->snArea.naDirname);
  514.     netResult(temp);
  515.     return;
  516.  
  517.     }
  518.   if (!realSetSpace(temp))
  519.     {
  520.     sPrintf(msgBuf.mbtext, "Send file didn't know what to do with %s.",
  521.     temp);
  522.     netResult(msgBuf.mbtext);
  523.  
  524.     }
  525.   else
  526.   doSendWork(mask, netSendFile);
  527.   homeSpace();
  528.  
  529.   }
  530. /************************************************************************/
  531. /*      doSendWork() does work of sysSendFiles()                        */
  532. /************************************************************************/
  533. void doSendWork(char *filename, void (*fn)(DirEntry *f))
  534.   {
  535.   Do_Stack_Check();
  536.   wildCard(fn, filename, FALSE, "", FALSE);
  537.  
  538.   }
  539. /************************************************************************/
  540. /*      DoDomainDirectory() work on a domain directory                  */
  541. /************************************************************************/
  542. void DoDomainDirectory(int i, char kill)
  543.   {
  544.   char num[8];
  545.   DOMAIN_FILE name;
  546.   Do_Stack_Check();
  547.   sPrintf(num, "%d", i);
  548.   makeSysName(name, num, &cfg.domainArea);
  549.   if (kill) rmdir(name);
  550.   else      mkdir(name);
  551.  
  552.   }
  553. /************************************************************************/
  554. /* Section 3.5. BAUD HANDLER:                                           */
  555. /*    The code in here has to discover what baud rate the caller is at. */
  556. /* For some computers, this should be ridiculously easy.                */
  557. /************************************************************************/
  558. #define NO_GOOD         0
  559. #define CR_CAUGHT       1
  560. #define NET_CAUGHT      2
  561. #define STROLL_CAUGHT   3
  562. /************************************************************************/
  563. /*      check_CR() Checks for CRs from the data port for half a second. */
  564. /************************************************************************/
  565. static short crcnt;
  566. static short timer1,timer2;
  567. char check_CR()
  568.   {
  569.   extern FILE *netLog;
  570.   struct timePacket ff;
  571.   int c=0;
  572.   int  clcnt=0;
  573.   char clast[8];  /* debug: last eight characters */
  574.   memset(clast,0,8);
  575.   Do_Stack_Check();
  576.   setTimer(&ff);
  577.   while (milliTimeSince(&ff) < timer1 )
  578.     {
  579.     if (MIReady())
  580.       {
  581.       if( c != 13 )crcnt = 0;
  582.       clast[clcnt & 0x07] = c = inp();
  583.       clcnt++;
  584.       switch (c)
  585.         {
  586.         case 27: return CR_CAUGHT;break;  /* one escape, or two CRs */
  587.         case 13:                          /* cr from user?, must have 2 */
  588.         if( ++crcnt >1)
  589.           {
  590.           return CR_CAUGHT;
  591.           };
  592.         break;
  593.         case 7:
  594.         if (cfg.BoolFlags.netParticipant)
  595.           {
  596.           if (receive(1) == 13)
  597.             {
  598.             crcnt = 1;
  599.             if (receive(1) == 69)
  600.               {
  601.               return NET_CAUGHT;
  602.               };
  603.             };
  604.           };
  605.         break;
  606.         case 68:
  607.         if (receive(1) == 79)
  608.           {
  609.           if (receive(1) == 35)
  610.             {
  611.             return STROLL_CAUGHT;
  612.             };
  613.           };
  614.         break;
  615.         default:
  616.         if (clcnt > 0 && cfg.BoolFlags.debug)
  617.           {
  618.           splitF(netLog,"%x %x %x %x\n ",clast[0],clast[1],clast[2],clast[3]);
  619.           splitF(netLog,"%x %x %x %x\n ",clast[4],clast[5],clast[6],clast[7]);
  620.           };
  621.         };
  622.       };
  623.     };
  624.   return NO_GOOD;
  625.   }
  626. /************************************************************************/
  627. /*      Find_Baud() Finds the baud from sysop and user supplied data.   */
  628. /************************************************************************/
  629. char Find_baud(char **whatRate)
  630.   {
  631.   char noGood = NO_GOOD;
  632.   int  Time = 0;
  633.   long  baudRunner;                    /* Only try for 60 seconds      */
  634.   char flag;
  635.   extern FILE *netLog;
  636.   extern long byteRate;
  637.   crcnt = 0;
  638.   Do_Stack_Check();
  639.   *whatRate = rates[9];  /* default to unknown */
  640.   flag = FALSE;
  641.   if ((baudRunner = getModemId()) != ERROR)
  642.     {
  643.     CitadelBaudRate(baudRunner, "Find_baud");
  644.     flag = TRUE;
  645.     if (cfg.BoolFlags.debug) splitF(netLog, "getModemId = %d\n",baudRunner);
  646.     };
  647.   if (cfg.DepData.LockPort >= 0 && !flag)  /* if serial port locked, use it */
  648.     {
  649.     baudRunner = cfg.DepData.LockPort;
  650.     flag = TRUE;
  651.     if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baudRunner);
  652.     };
  653.   pause(10);                    /* To clear line noise and eat banner */
  654.   while (MIReady())   inp();   /* eat noise and banners        */
  655.   if( cfg.DepData.LockPort >= 0 || flag )
  656.     {
  657.     timer1 = 50;               /* time spent looking for User/Net session */
  658.     timer2 =  4;               /* number of autobaud attempts */
  659.     }
  660.   else
  661.     {
  662.     timer1 = 75;                /* time spent looking for User/Net session */
  663.     timer2 = (cfg.sysBaud+1)*3; /* autobaud attempts, try 3 attempts */
  664.     baudRunner = 0;
  665.     };
  666.   while (gotCarrier() && noGood == NO_GOOD &&  (Time < timer2))
  667.     {
  668.     Time++;
  669.     if( !flag )
  670.       {
  671.       CitadelBaudRate(baudRunner,"Find_baud");
  672.       };
  673.     noGood = check_CR();
  674.     if (noGood == NO_GOOD && !flag)
  675.       {
  676.       if( baudRunner++ > cfg.sysBaud )baudRunner = 0;
  677.       };
  678.     };
  679.   if( noGood == NO_GOOD && !flag )
  680.     {
  681.     baudRunner = cfg.sysBaud;
  682.     if( !flag ) CitadelBaudRate(baudRunner, "Find_baud");
  683.     };
  684.   LastBaudIndex = baudRunner;
  685.   *whatRate     = rates[baudRunner];
  686.   byteRate      = (atol(rates[baudRunner]) ) / 10L;
  687.   if (cfg.BoolFlags.debug) splitF(netLog, "Time:%d Baud:%s\n",Time,*whatRate);
  688.   if (noGood == NET_CAUGHT)
  689.     {
  690.     netController(0, 0, NO_NETS, ANY_CALL, 0);
  691.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->Net_Caught\n",*whatRate);
  692.     return FALSE;       /* pretend nothing happened */
  693.  
  694.     }
  695.   if (noGood == STROLL_CAUGHT)
  696.     {
  697.     StrollIt();
  698.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->STROLL_Caught\n",*whatRate);
  699.     return FALSE;       /* pretend nothing happened */
  700.  
  701.     }
  702.   if (cfg.BoolFlags.debug) splitF(netLog, "Baud-%s-->other\n",*whatRate);
  703.   return (char)(noGood == CR_CAUGHT || flag); /* return TRUE if USER */
  704.  
  705.   }
  706. /************************************************************************/
  707. /*      getModemId() Try to read baud id from modem                     */
  708. /************************************************************************/
  709. #define BA_BUF_SIZE     80
  710.   extern char results_debug;  /* turn on to debug modem results codes */
  711.   extern char results_cid;    /* turn on to collect caller ID info if present */
  712.  
  713. long getModemId()
  714.   {
  715.   char c, buffer[BA_BUF_SIZE];         /* Hopefully, overkill */
  716.   extern FILE *netLog;
  717.   struct timePacket ff;
  718.   int i;
  719.   long baud;
  720.   char save_all = FALSE;
  721.   int *j;
  722.   extern char ResultCodesAvailable;
  723.   Do_Stack_Check();
  724.   if (!ResultCodesAvailable)
  725.     {
  726.     if (cfg.DepData.LockPort >= 0 )  /* if serial port locked, use it */
  727.       {
  728.       baud = cfg.DepData.LockPort;
  729.       if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baud);
  730.       }
  731.     else baud = ERROR;
  732.     return baud;
  733.     };
  734.   setTimer(&ff);
  735.   i = 0;
  736.   while (timeSince(&ff) < 5l)
  737.     {
  738.     if (MIReady())
  739.       {
  740.       if ((c = inp()) == '\r')
  741.         {
  742.         buffer[i] = 0;
  743.         if( i <= 1 )continue;
  744.         if( buffer[0] == 'E' && buffer[1]== 07 )
  745.           {
  746.           if (cfg.DepData.LockPort >= 0 )  /* if serial port locked, use it */
  747.             {
  748.             baud = cfg.DepData.LockPort;
  749.             if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baud);
  750.             }
  751.           else baud = ERROR;
  752.           return baud;
  753.           };
  754.         if( results_debug )splitF(NULL, "buffer search:-%s-\n",buffer);
  755.         if( save_all )splitF(NULL, "CID:%s\n",buffer);
  756.         j = (int *) SearchList(&ResList, buffer);
  757.         if (j != NULL)
  758.           {
  759.           switch (*j)
  760.             {
  761.             case R_RING:
  762.               if( results_cid )  /* toggle to collect info between rings */
  763.                 {
  764.                 save_all = TRUE;
  765.                 };
  766.               break;
  767.             case R_AOK:      break;
  768.             case R_NOCARR:
  769.             case R_BUSY:
  770.             case R_DIAL:
  771.             case R_NODIAL:   return ERROR;
  772.             case R_300:
  773.             case R_1200:
  774.             case R_2400:
  775.             case R_4800:
  776.             case R_9600:
  777.             case R_14400:
  778.             case R_19200:
  779.             case R_38400:
  780.             case R_57600:
  781.             return (long)*j;
  782.             default:
  783.               splitF(NULL, "Modem text not in RESULTS.SYS\n");
  784.             break;
  785.  
  786.             };
  787.           i = 0;
  788.  
  789.           }
  790.         else i = 0;
  791.  
  792.         }
  793.       else
  794.         {
  795.         if (c != '\n')
  796.           {
  797.           buffer[i++] = c;
  798.           }
  799.         if (i >= BA_BUF_SIZE - 4)
  800.           {
  801.           /* Fudge factor */
  802.           i = 0;
  803.           if( results_debug )splitF(NULL, "buffer flush:-%s-\n",buffer);
  804.  
  805.           }
  806.  
  807.         }
  808.  
  809.       }
  810.  
  811.     }
  812.   buffer[i] = 0;      /* debug for now */
  813.   splitF(NULL, "FAILURE to find in RESULTS.SYS:%s\n", buffer);
  814.   if (cfg.DepData.LockPort >= 0 )  /* if serial port locked, use it */
  815.     {
  816.     baud = cfg.DepData.LockPort;
  817.     if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baud);
  818.     }
  819.   else baud = ERROR;
  820.   return baud;
  821.   }
  822. /************************************************************************/
  823. /*      getNetBaud()  gets baud of network caller -- refer to SysDep.doc*/
  824. /************************************************************************/
  825. char getNetBaud()
  826.   {
  827.   extern FILE *netLog;
  828.   long   Time, baudRunner;
  829.   extern long byteRate;
  830.   char        found = FALSE, notFinished;
  831.   extern char inNet;
  832.   Do_Stack_Check();
  833.   baudRunner = cfg.sysBaud;
  834.   /* If anytime answer, then we already have baud rate */
  835.   if (inNet == ANY_CALL || inNet == STROLL_CALL)
  836.     {
  837.     found      = TRUE;
  838.     baudRunner = LastBaudIndex;
  839.  
  840.     }
  841.   else if (GetFirst(&ResList))
  842.     {
  843.     if ((baudRunner = getModemId()) != ERROR)
  844.       {
  845.       found = TRUE;
  846.  
  847.       }
  848.  
  849.     }
  850.   pause(10);         /* Pause a  second */
  851.   if (found)
  852.     {
  853.     CitadelBaudRate(baudRunner, "getNetBaud");
  854.     byteRate = atol(rates[baudRunner]) / 10L;
  855.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  856.       {
  857.       if (check_for_init(FALSE)) return TRUE;
  858.       }
  859.     if (gotCarrier())
  860.       {
  861.       outFlag = IMPERVIOUS;
  862.       Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  863.  
  864.       }
  865.  
  866.     }
  867.   else
  868.     {
  869.     while (MIReady())   inp();          /* Clear garbage        */
  870.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  871.       {
  872.       for (notFinished = TRUE, baudRunner = 0;
  873.       gotCarrier() && notFinished;)
  874.         {
  875.         byteRate = atol(rates[baudRunner]) / 10L;
  876.         CitadelBaudRate(baudRunner, "getNetBaud");
  877.         if (check_for_init(FALSE)) return TRUE;  /* get connection */
  878.         notFinished = !(baudRunner == cfg.sysBaud);
  879.         baudRunner++;
  880.  
  881.         }
  882.  
  883.       }
  884.     if (gotCarrier())
  885.       {
  886.       outFlag = IMPERVIOUS;
  887.       for (baudRunner = cfg.sysBaud; baudRunner > -1; baudRunner--)
  888.         {
  889.         CitadelBaudRate(baudRunner, "getNetBaud");
  890.         Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  891.         }
  892.       outFlag = OUTOK;
  893.  
  894.       }
  895.  
  896.     }
  897.   if (!gotCarrier()) splitF(netLog, "GetNetBaud:Lost carrier\n");
  898.   killConnection();
  899.   return FALSE;
  900.  
  901.   }
  902. /************************************************************************/
  903. /* Section 3.3. CONSOLE HANDLING:                                       */
  904. /*    These functions are responsible for handling console I/O.         */
  905. /************************************************************************/
  906. /************************************************************************/
  907. /*      mputChar()                                                      */
  908. /************************************************************************/
  909.  
  910. int ConPutChar(char myChar);
  911.  
  912. void mputChar(char c)
  913.   {
  914.   extern char ChatMode;
  915.   Do_Stack_Check();
  916.   if ((c == '\0') || (c == BELL && cfg.BoolFlags.noChat && !onConsole))  return;
  917.   if (!(whichIO == CONSOLE || onConsole) && !anyEcho)  return;
  918.   if (c != ESC &&       (echo == BOTH ||
  919.   (whichIO == CONSOLE && (echo != NEITHER || echoChar))))
  920.     {
  921.     ConPutChar(c);
  922.  
  923.     }
  924.   /* if (onConsole && !ChatMode && ConDelay > 0) pause(ConDelay); */
  925.  
  926.   }
  927.